perm filename MACROS.MID[NET,MRC]1 blob sn#247871 filedate 1976-11-16 generic text, type T, neo UTF8
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;									;;
;;	MM	MM	A	CCCCCC	 RRRRRR	    OOOO     SSSS	;;
;;	MMMM  MMMM    AA AA    CC     C	 RR    R  OO	OO  S		;;
;;	MM  MM	MM  AA	   AA  CC	 RRRRRR	  OO	OO   SSSS	;;
;;	MM	MM  AAAAAAAAA  CC	 RR R	  OO	OO	 S	;;
;;	MM	MM  AA	   AA  CC     C	 RR  R	  OO	OO  S	 S	;;
;;	MM	MM  AA	   AA	CCCCCC	 RR   R	    OOOO     SSSS	;;
;;									;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

	Subttl	General-purpose macro library

; Mark Crispin, AI, February 1976; Last updated: MRC October 17, 1976

;  This file contains symbolic and macro definitions that many of my programs
; use.  It is an experiment in higher-level assembly language programming.
;  Thanks to MSC, RMS, GLS, MOON, and RG for help in writing this package.

If2 .ineof				; only read this file on pass 1
.auxil					; don't cref this file's unused symbols
.nstgw					; do not allow storage words

Ifn 0,[					; for @ happiness
.insrt SYSTEM;TTYDEF >
.insrt SYSTEM;BITS >
]

; These symbols are temporaries that the user should never have to worry about.

.xcref TEMP%%,FLAG%%,%ADD,%ADDI,%SUB,%SUBI,%FADR,%FADRI,%FSBR,%FSBRI

; MIDAS environment alteration and recording(date, time, etc.)

.format 30,2704←24.			; make A, format treat A like an ac
.format 34,00222704←12.			; make A,B format treat A like an ac

Ife .OSMIDAS-('ITS),[			; ** ITS MIDAS **
.aop .RDATIM				; get date and time of assembly
%ASTIM==.AVAL1				; time of assembly in SIXBIT (HHMMSS)
%ASDAT==.AVAL2				; date of assembly in SIXBIT (YYMMDD)
]					; ** End of ITS MIDAS **
Ifn .OSMIDAS-('ITS),[			; ** DEC MIDAS **
%ASTIM==.op MSTIME			; time of assembly in milliseconds
%ASDAT==.op DATE			; date of assembly in DEC format
]					; ** End of DEC MIDAS **
%VERSION==.FNAM2			; version when assembled

	Subttl	Instruction, field definitions

; PDP-10 word field definitions

%INFIN==377777777777			; infinity
%MINFI==400000000000			; minus infinity
%LHALF==777777000000			; left half word
%RHALF==000000777777			; right half word
%FWORD==777777777777			; full word
%ZEROS==000000000000			; zeroes

; Instruction fields

%ICOPC==777000,,			; opcode
%ICACF==000740,,			; ac field
%ICIOP==700340,,			; I/O opcode
%ICIDV==077400,,			; I/O device channel
%ICIND==000020,,			; indirect bit
%ICIDX==000017,,			; index field
%ICADR==777777				; address

; Special forms of PDP-10 instructions

JOV=jfcl 10,				; jump on overflow
JCRY0=jfcl 4,				; jump on carry 0
JCRY1=jfcl 2,				; jump on carry 1
JCRY=jfcl 6,				; jump on carry 0 or 1
JFOV=jfcl 1,				; jump on floating overflow
JEN=jrst 12,				; jump and enable PI system
HALT=jrst 4,				; stop the processor
JRSTF=jrst 2,				; jump and restore flags
PORTAL=jrst 1,				; KI/KL gatekeeper(not used on ITS)
MAP=257000,,				; map an address(not used on ITS)
RSW=datai apr,				; read switches
SLITE=datao pi,				; set program lights

;  The following are used by a subroutine that calls a second
; subroutine that is to return to the former's caller.

; Instruction				Replaces
; -----------				--------

PJRST==jrst				; pushj/popj
PJRSTF==jrstf				; pushj/popj
PJSP==jsp				; movei .+1/pushj/popj
PJUMPL==jumpl				; jump??/popj/pushj/popj
PJMPLE==jumple
PJUMPN==jumpn
PJUMPG==jumpg
PJMPGE==jumpge

;  The following are mostly for convenience in using DDT.

Ifndef P,p==17				; conventional stack pointer ac

SAVE=push p,				; save value on stack
RETR=pop p,				; retrieve value from stack
CALL=pushj p,				; save PC on stack and jump
RETURN=popj p,				; restore PC from stack

	Subttl	General pseudo-ops

; TMPLOC - assemble into a certain location
;	tmploc loc,value

Define TMPLOC ?loc=0,value=0
 TEMP%%==. ? .==loc ? value ? .==TEMP%%
Termin

; END - terminate assembly, expunge temporary symbols
;	end <start address>

Equals %END,END				; make %END terminate assembly

Define END addr
 If2 Expunge TEMP%%,FLAG%%,%ADD,%ADDI,%SUB,%SUBI,%FADR,%FADRI,%FSBR,%FSBRI
 %end addr
Termin

; ND. - define a symbol if it is not defined
;	nd. symbol=value

Define ND. defn
 Irps TEMP%%,,[defn]
  Ifdef TEMP%%,Null
  .istop
 Termin
 .else defn
Termin

; ACDEF. - define consecutive accumulators, I/O channels, etc.
; 	starting at 1.
;	acdef. <ac-list>

Define ACDEF. aclist
 Irps TEMP%%,,[aclist]
  nd. TEMP%%==.IRPCNT+1
  Ifge TEMP%%-20,.err TEMP%%	Magnitude > 17
 Termin
Termin

; FLAG. - dynamically generate a bit flag
;	flag. flag		;to generate a flag
;	flag.			;to initialize the mechanism

Define FLAG. bit
 Ifb bit,FLAG%%==%MINFI ? .istop
 Ifndef FLAG%%,.err bit	Flags not initialized
 Ife FLAG%%,.err bit	Too many flags
 bit==FLAG%%
 FLAG%%==FLAG%%←-1
Termin

; IOWD - generate a DEC IOWD
;	iowd length,address

Define IOWD ?len,adr
<-len,,adr-1>Termin

; SWDEF. - define an assembly switch
;	swdef. [definition];description

Define SWDEF. defn,desc/
 If1,[
  defn
  Printx\!desc!:  !defn! \
  irps switch,,[defn]
   .ttymac cruft/
    ifnb [cruft][switch==cruft]
   termin
   .istop
  termin
 ]
Termin

	Subttl	Byte manipulation pseudo-ops

; POINT. - MACRO-10 style point pseudo-op
;	point. length,address,position

Define POINT. ?s,addr,b=-1
<<<<35.-.radix 10.,b>&77>←30.\<<.radix 10.,s>&77>←24.> addr>Termin

; WID. - compute the width of a mask
;	wid. mask

Define WID. ?mask
<.ldb 300600,.bp mask>Termin

; POS. - compute the position of a mask
;	pos. mask

Define POS. ?mask
<35.-.tz mask>Termin

; MASK. - build a mask pointed to by point wid,loc,pos
;	mask. width,position

Define MASK. ?wid,pos
<<<1←wid>-1>←<35.-pos>>Termin

; RGHBT. - generate the rightmost bit in a mask
;	rghbt. mask

Define RGHBT. ?mask
<mask&-mask>Termin

; LFTBT. - generate the leftmost bit in a mask
;	lftbt. mask

Define LFTBT. ?mask
<1←<35.-.lz mask>>Termin

; FILIN. - fill in ones from leftmost bit of mask to rightmost bit
;	filin. mask

Define FILIN. ?mask
<.bm .bp mask>Termin

; INSVL. - position value in mask
;	insvl. value,mask

Define INSVL. ?value,mask
<<value←.tz mask>&mask>Termin

; RJUST. - right justify a mask
;	rjust. mask

Define RJUST. ?mask
<mask←<-.tz mask>>Termin

; LJUST. - left justify a mask
;	ljust. mask

Define LJUST. ?mask
<mask←.lz mask>Termin

	Subttl	Text accumulation pseudo-ops

; CINFO. - macro to clear and/or initialize the text mechanism
;	cinfo.

Define CINFO.
 Define INFO. ocruft
  ocruft
 Termin
Termin

; REDEF. - macro to add text to the mechanism.  It adds a <crlf>
;	at the end.
;	redef. [...text...]

Define REDEF. ncruft
 info. [Define INFO. ocruft
  ocruft]ncruft
 Termin
Termin

; INFO. - macro (hacked by CINFO. and REDEF.) to dump out the text.
;	info.

	Subttl	High-level instructions

Ife .OSMIDAS-('ITS),[			; ** ITS MIDAS only **
; SYSCAL - macro to generate a symbolic system call
;	syscal call,[args]

Define SYSCAL call,args
 .call [%MINFI
	SIXBIT/call/
	args
	%MINFI\%CLERR $ERCOD']
Termin

; SYSCAL op-codes

%CLARG==000000,,			; argument
%CLARI=001000,,				; immediate argument
%CLVAL=002000,,				; value
%CLERR=003000,,				; error
%CLCTL=004000,,				; control
%CLCTI=005000,,				; immediate control

;  CLARG. and CLCTL. are to allow for ambigious immediates in a SYSCAL
; argument and control argument.

Define CLARG. arg
 TEMP%%=arg
 Ifn TEMP%%&%LHALF,%CLARG [TEMP%%]
 .else %CLARI TEMP%%
Termin

Define CLCTL. ctl
 TEMP%%==ctl
 Ifn TEMP%%&%LHALF,%CLCTL [TEMP%%]
 .else %CLCTI TEMP%%
Termin

; UGET - fetch a user variable
;	uget name,loc,channel

Define UGET var,loc,chnl
 Ifb chnl,.suset [.R!var,,loc]
 .else .uset chnl,[.R!var,,loc]
Termin

; USET - set a user variable
;	uset name,loc,channel

Define USET var,loc,chnl
 Ifb chnl,.suset [.S!var,,loc]
 .else .uset chnl,[.S!var,,loc]
Termin

; USETI - set a user variable, immediate
;	useti name,value

Define USETI var,val,chnl
 Ifb chnl,.suset [.S!var,,[val]]
 .else .uset chnl,[.S!var,,[val]]
Termin

; PEEK - peek at an ITS system location
;	peek ac,name

Define PEEK ac,name
 movx ac,<squoze 0,name>
 .eval ac,
  .lose
 hrli ac,ac
 movss ac
 .getloc ac,
Termin
]					; ** End of ITS MIDAS **

; INSIRP - repeat over an instruction with various addresses
;	insirp inst,address(es)

Define INSIRP inst,addrs
 Irps TEMP%%,,[addrs]
  inst,TEMP%%
 Termin
Termin

; JUMPPT - jump depending upon processor type
;	jumppt ac,PDP-6,KA-10,KI-10,KL-10
; ac is a temporary ac not equal to zero.

Define JUMPPT ac=1,cp166=0,ka10=0,ki10=0,kl10=0
Ife ac,.err JUMPPT	1st arg zero
If2,Ife cp166*ka10*ki10*kl10,.err JUMPPT	Null processor argument
	jfcl 1,.+1			; clear PDP-6 PC change flag
	jrst .+1			; set PC change flag on PDP-6
	jfcl 1,cp166			; if flag is on, PDP-6
	movx ac,-1(,,-2)		; ac := -2,,-1
	aobjp ac,ka10			; non-zero ac means KA-10
	movx ac,%zeros			; ac := 0
	blt ac,				; KI/KL test
	jumpe ac,ki10			; zero ac means KI-10
	jrst kl10			; else it is a KL-10
Termin

; STORE - macro to place a constant in a block of locations
;	store <constant>,<first location>,<last location>,<temp ac>

;		** Note Well **

; May generate more than one word of code.
; If last location is not specified, it is a "MOVXM".  If temp ac is
; not specified, ac 0 is used.  <== Note Well !!

Define STORE ?cons=0,first=0,last=0,ac=0
 TEMP%%=0
 Ife cons,setzm first ? TEMP%%=-1
 Ife cons+1,setom first ? TEMP%%=-1
 Ife cons-1,setzm first ? aos first ? TEMP%%=-1
 Ife cons+2,setom first ? sos first ? TEMP%%=-1
 Ife TEMP%%,[movx ac,cons
  movem ac,first]
 Ifn last,move ac,[first,,first+1] ? blt ac,last
Termin

; MOVX - macro to load an immediate value into an accumulator

Define MOVX ?ac=0,flag=0
 TEMP%%=flag
 Ife TEMP%%,setz ac, ? .istop
 Ife TEMP%%+1,seto ac, ? .istop
 Ife TEMP%%&%LHALF,movei ac,TEMP%% ? .istop
 Ife TEMP%%&%RHALF,movsi ac,(TEMP%%) ? .istop
 Ife <TEMP%%←-18.>-%RHALF,hrroi ac,TEMP%% ? .istop
 Ife <TEMP%%←18.>-%LHALF,hrloi ac,(TEMP%%-%RHALF) ? .istop
 move ac,[TEMP%%]
Termin

; CAX?? - compare ac with immediate and skip under condition

Irp code,,[,L,LE,E,G,GE,N,A]
 Define CAX!code ?ac=0,value=0
  TEMP%%=value
  Ife TEMP%%&%LHALF,CAI!code ac,TEMP%%
  .else CAM!code ac,[TEMP%%]
 Termin
Termin

; Arithmetic operations

Irps code,,[%ADD,%SUB,MUL,IMUL,DIV,IDIV]
 Define code!X ?ac=0,value=0
  TEMP%%=value
  Ife TEMP%%&%LHALF,code!I ac,TEMP%%
  .else code ac,[TEMP%%]
 Termin
Termin

Define ADDX ?ac=0,value=0
 TEMP%%=value
 Ife <TEMP%%←-18.>-%RHALF,subi ac,-TEMP%%
 .else %addx ac,TEMP%%
Termin

Equals %ADD,ADD ? Equals %ADDI,ADDI

Define SUBX ?ac=0,value=0
 TEMP%%=value
 Ife <TEMP%%←-18.>-%RHALF,addi ac,-TEMP%%
 .else %subx ac,TEMP%%
Termin

Equals %SUB,SUB ? Equals %SUBI,SUBI

Irps code,,[%FADR,%FSBR,FMPR,FDVR]
 Define code!X ?ac=0,value=0
  TEMP%%==value
  Ife TEMP%%&%RHALF,code!I ac,(TEMP%%)
  .else code ac,[TEMP%%]
 Termin
Termin

Define FADRX ?ac=0,value=0
 TEMP%%=value
 Ife <TEMP%%←18.>-%LHALF,fsbri ac,(%LHALF&-TEMP%%)
 .else %fadrx ac,TEMP%%
Termin

Equals %FADR,FADR ? Equals %FADRI,FADRI

Define FSBRX ?ac=0,value=0
 TEMP%%=value
 Ife <TEMP%%←18.>-%LHALF,fadri ac,(%LHALF&-TEMP%%)
 .else %fsbrx ac,TEMP%%
Termin

Equals %FSBR,FSBR ? Equals %FSBRI,FSBRI

; BTSWAP - swap states of two bits in an accumulator

Define BTSWAP ?ac=0,bit1=0,bit2=0
 Repeat 3,txce ac,bit1\bit2
Termin

; TX?? - test ac under immediate mask with option and skip under
;	condition

Irp action,,[N,Z,O,C]
 Irp code,,[E,N,A]
  Define TX!action!!code ?ac=0,flag=0
   TEMP%%=flag
   Ife TEMP%%&%RHALF,Ifn TEMP%%,TL!action!!code ac,(TEMP%%) ? .istop
   Ife TEMP%%&%LHALF,TR!action!!code ac,TEMP%% ? .istop
   TD!action!!code ac,[TEMP%%]
  Termin
 Termin
Termin

Define TXZA ?ac=0,flag=0
 TEMP%%=flag
 Ife TEMP%%,trna ac,%zeros ? .istop
 Ife TEMP%%-%FWORD,tdza a,a ? .istop
 Ife TEMP%%&%RHALF,tlza ac,(TEMP%%) ? .istop
 Ife TEMP%%&%LHALF,trza ac,TEMP%% ? .istop
 tdza ac,[TEMP%%]
Termin

Define TXN ?ac=0,flag=0
 trn ac,<,,flag>
Termin

Define TXZ ?ac=0,flag=0
 TEMP%%=flag
 Ife TEMP%%-%FWORD,movx ac,%ZEROS ? .istop
 Ife <TEMP%%←-18.>-%RHALF,andi ac,#TEMP%% ? .istop
 Ife TEMP%%←18.,Ifn TEMP%%,tlz ac,(TEMP%%) ? .istop
 Ife TEMP%%←-18.,andcmi ac,TEMP%% ? .istop
 and ac,[#TEMP%%]
Termin

Define TXO ?ac=0,flag=0
 TEMP%%=flag
 Ife TEMP%%-%FWORD,movx ac,%FWORD ? .istop
 Ife <TEMP%%←-18.>-%RHALF,orcmi ac,#TEMP%% ? .istop
 Ife TEMP%%←18.,Ifn TEMP%%,tlo ac,(TEMP%%) ? .istop
 Ife TEMP%%←-18.,iori ac,TEMP%% ? .istop
 ior ac,[TEMP%%]
Termin

Define TXC ?ac=0,flag=0
 TEMP%%=flag
 Ife TEMP%%-%FWORD,setca ac, ? .istop
 Ife <TEMP%%←-18.>-%RHALF,eqvi ac,#TEMP%% ? .istop
 Ife TEMP%%←18.,Ifn TEMP%%,tlc ac,(TEMP%%) ? .istop
 Ife TEMP%%←-18.,xori ac,TEMP%% ? .istop
 xor ac,[TEMP%%]
Termin

; IORX, ANDX, XORX, EQVX are super-random versions of TX??

Equals IORX,TXO

Define ANDX ?ac=0,flag=0
 TEMP%%=flag
 txz ac,#TEMP%%
Termin

Equals XORX,TXC

Define EQVX ?ac=0,flag=0
 TEMP%%=flag
 xorx ac,#flag
Termin

.ystgw					; allow storage words again

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;		*** The END ***			;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
β